// 1.观察者模式： 一种设计模式，一个对象（主题）维护一个观察者列表，并在状态改变时---自动--通知他们
// 2. 关键组件： 主题： 维护观察者列表，提供用于增加或删除观察者的接口。  观察者： 提供一个更新接口，以便在主题状态改变时被通知
//3. 交互方式：观察者直接接收来自主题的更新。
let depId = 0; //记录调用了多少次的 Dep也就是，new了多少个dep实例
export class Dep {
  // 观察者模式中的  主题对象 用来管理各个观察者
  constructor() {
    this.subs = [];
    this.depId = depId++;
  }
  // 收集watcher---watcher收集dep-相互收集
  subScribe() {
    console.log(this, "subScribesubScribe--sub");
    // 1.我希望watcher可以存放dep

    // 2. watcher内部添加相关联的dep，Dep.tatget == 当前的watcher==>addDep==>watcher实例上的方法
    // 双向记忆  watcher 内 去添加dep
    Dep.target.addDep(this); // 此处this===>当前dep实例
  }
  // dep-收集watcher
  addSubWatcher(watcher) {
    console.log(watcher, "watcherwatcher--addSubWatcher");
    this.subs.push(watcher);
  }
  // 发布---状态改变时候-自动-通知

  notify(data) {
    this.subs.forEach((watcher) => watcher.update(data));
  }
}

// 添加watcher
Dep.target = null; //给Dep添加一个属性 叫target 记录当前添加的watcher
let stack = []; //处理多个watcher 用一个栈来存储
export function pushWatcher(watcher) {
  Dep.target = watcher; // 保留watcher
  // 入栈--为了计算属性的watcher和 渲染函数的watcher互相记忆，当计算属性更新的时候，如果在页面上用到该属性，需要通过watcher进行收集依赖，来进行自动更新
  stack.push(watcher);
  console.log(
    stack,
    watcher,
    "----computed-or-渲染函数--pushWatcher-收集当前的watcher",
  );
}
// 取消当前操作的watcher
export function popTargetWatcher() {
  // Dep.target = null; //原来的时候只有一个watcher-渲染watcher，，，，[渲染watcher, 计算属性a的watchera,计算属性b的watcherb]
  stack.pop(); // 解析完watcher之后 就出栈
  Dep.target = stack[stack.length - 1]; // 出栈--返回上一个watcher
}

// 观察者模式（Observer pattern）是一种设计模式，它定义了对象之间的一对多的依赖关系，当一个对象的状态发生改变时，所有依赖于它的对象都将得到通知并自动更新。在JavaScript中，观察者模式可以用来实现事件驱动的编程，以下是实现观察者模式的基本步骤：

// 1. **定义Subject（被观察者）**:
//    Subject负责维护一份观察者列表，提供用于添加、移除和通知观察者的方法。

// 2. **定义Observer（观察者）**:
//    Observer通常包含一个 `update` 方法，当Subject的状态发生变化时，`update` 方法会被调用。

// 3. **注册观察者**:
//    观察者需要注册自己到Subject，以便当Subject状态改变时能接收到通知。

// 4. **状态更新与通知**:
//    当Subject中的某个状态（也可以是整个Subject的状态）发生变化时，Subject会调用自己的通知方法，遍历所有注册的观察者，并调用它们的 `update` 方法。

// 下面是一个简单的JavaScript例子，展示了如何实现观察者模式：

// ```javascript
// // Subject类
// class Subject {
//   constructor() {
//     this.observers = []; // 观察者列表
//   }

//   // 添加观察者
//   addObserver(observer) {
//     this.observers.push(observer);
//   }

//   // 移除观察者
//   removeObserver(observer) {
//     const index = this.observers.indexOf(observer);
//     if (index > -1) {
//       this.observers.splice(index, 1);
//     }
//   }

//   // 通知所有观察者
//   notify(data) {
//     for (let observer of this.observers) {
//       observer.update(data);
//     }
//   }
// }

// // Observer类
// class Observer {
//   constructor(name) {
//     this.name = name;
//   }

//   // 更新方法
//   update(data) {
//     console.log(`${this.name} received data: `, data);
//   }
// }

// // 使用
// const subject = new Subject();

// const observer1 = new Observer('Observer 1');
// const observer2 = new Observer('Observer 2');

// subject.addObserver(observer1);
// subject.addObserver(observer2);

// subject.notify('Hello World!');  // Observer 1 and Observer 2 will receive data
// ```

// 在这个例子中，Subject负责管理观察者并通知他们，每个Observer实例都有一个 `update` 方法，用于接收Subject的状态变化。当调用 `subject.notify()` 时，所有注册到该Subject的观察者都会被通知。

// 观察者模式在很多现代JavaScript库和框架中都有广泛应用，比如Vue和React中的状态管理。它允许应用程序中的不同部分在不直接相互引用的情况下进行通信，这有助于减少组件之间的耦合，并提高代码的可维护性。
